package com.mzj.saas.mservice.idcard.service;

import com.alibaba.fastjson.JSONObject;
import com.mzj.saas.commons.HttpUtils;
import com.mzj.saas.commons.ResultBean;
import com.mzj.saas.commons.vo.redis.TokenRedisVo;
import com.mzj.saas.mservice.eligible.repository.EligibleRepository;
import com.mzj.saas.mservice.idcard.vo.IdcardVO;
import com.mzj.saas.mservice.sys.entity.AppUser;
import com.mzj.saas.mservice.sys.repository.AppUserRepository;
import com.mzj.saas.mservice.sys.service.AppUserService;
import com.mzj.saas.redis.RedisService;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

@Service
public class IdcardService {

    private static final Logger log = LoggerFactory.getLogger(IdcardService.class);

    @Autowired
    private AppUserRepository appUserRepository;
    @Autowired
    private RedisService redisService;
    @Autowired
    private EligibleRepository eligibleRepository;
    @Autowired
    private AppUserService appUserService;
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Value("${app.code}")
    private String appcode;

    @Value("${oca.idcard.host}")
    private String ocaHost;

    @Value("${oca.idcard.path}")
    private String ocaPath;

    /**
     * 简单身份认证（AppCode） -  身份证识别
     *
     * @param accessToken
     * @param path        图片url或图片base64
     * @param side        身份证正反面类型:face/back
     * @return
     */
    public ResultBean<IdcardVO> idcardToAppCode(String accessToken, String path, String side, Integer type, Integer userType) {
        try {
            //记录日志
            log.info(" 身份证识别, side={}, type={}, userType={}", side, type, userType);
            //获取用户登录权限
            TokenRedisVo tokenRedisVo = redisService.findTokenVo(accessToken);
            //用户权限的鉴定
            if (tokenRedisVo == null) {
                return ResultBean.failedResultOfToken();
            }
            //获取用户ID
            String userId = tokenRedisVo.getId();
            //获取用户登录类型
            Integer loginType = tokenRedisVo.getLoginType();
            //查询用户数据
            AppUser appUser = appUserService.findByIdAndStatus(userId, 1, loginType);
            //判断用户是否存储
            if (appUser == null) {
                return ResultBean.failedResultOfParamWithMsg("用户不存在");
            }

            if (StringUtils.isBlank(path) || StringUtils.isBlank(side)) {
                return ResultBean.failedResultOfParamWithMsg("参数错误");
            }

            Map<String, String> headers = new HashMap<String, String>();
            headers.put("Authorization", "APPCODE " + appcode);
            headers.put("Content-Type", "application/json; charset=UTF-8");

            Map<String, String> querys = new HashMap<String, String>();
            JSONObject configObj = new JSONObject();
            configObj.put("side", side);
            String config_str = configObj.toString();
            JSONObject requestObj = new JSONObject();
            requestObj.put("image", path);
            requestObj.put("configure", config_str);
            String bodys = requestObj.toString();

            HttpResponse response = null;
            try {
                response = HttpUtils.doPost(ocaHost, ocaPath, "POST", headers, querys, bodys);
                int stat = response.getStatusLine().getStatusCode();
                if (stat != 200) {
                    log.warn("Http code:{}", stat);
                    log.warn("http header error msg:{}", response.getFirstHeader("X-Ca-Error-Message"));
                    log.warn("Http body error msg:{}", EntityUtils.toString(response.getEntity()));
                    return ResultBean.failedResultWithMsg(EntityUtils.toString(response.getEntity()));
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                return ResultBean.failedResultWithMsg("识别异常, 请上传正确身份证图片或稍后重试");
            }

            String res = EntityUtils.toString(response.getEntity());

            log.info("idcard res = {}", res);
            IdcardVO vo = JSONObject.parseObject(res, IdcardVO.class);

            String num = vo.getNum();
            if (type != null && userType != null) {
                if (userType == 1) {
                    AppUser user = appUserRepository.findByCardNumber(num);
                    if (user == null) {
                        return ResultBean.failedResultWithMsg("用户未实名认证，无法申请");
                    } else {
                        if (user.getCertificationStatus() == 0) {
                            return ResultBean.failedResultWithMsg("用户未实名认证，无法申请");
                        }
                    }

                    if (type == 1 && !appUser.getName().equals(vo.getName())) {
                        return ResultBean.failedResultWithMsg("身份证信息与当前用户不符，无法申请");
                    }

                    Long count1 = jdbcTemplate.queryForObject("select count(1) from `saas_house_eligible_apply` a \n" +
                            "where a.apply_status in (1,2,3,10) and a.card_number = ?", new Object[]{num}, Long.class);
                    Long count2 = jdbcTemplate.queryForObject("select count(1) from `saas_house_eligible_apply_cohabit` c left join `saas_house_eligible_apply` a on c.apply_id = a.id\n" +
                            "where a.apply_status in (1,2,3,10) and c.card_number = ?", new Object[]{num}, Long.class);
                    if (count1 + count2 > 0) {
                        return ResultBean.failedResultWithMsg("承租人信息已有公租房申请记录，请核实后提交");
                    }
                }
            }

            return ResultBean.successfulResult(vo);
        } catch (Exception e) {
            log.error("身份证识别异常, " + e.getMessage(), e);
            return ResultBean.failedResultOfException();
        }
    }

    /**
     * 签名认证 - 身份证识别
     *
     * @param accessToken
     * @param path
     * @return
     */
    public ResultBean<IdcardVO> idcardToSign(String accessToken, String path, String side) {
        return null;
    }
}

